網路上有很多文章與範例在解釋6大原則,
但是還是很難只看一篇就能了解。
一言以蔽之 : 子類別必須可以替換父類別的功能
雖然是很簡單的觀念,但是理解起來還是很抽象。
今天就來統整一下這個原則吧
以下截自wiki
里氏替換原則(Liskov Substitution principle)是對子類型的特別定義。
它由芭芭拉·里斯科夫(Barbara Liskov)在1987年在一次會議上名為「數據的抽象與層次」的演說中首先提出。
里氏替換原則的內容可以描述為: 「派生類(子類)對象可以在程式中代替其基類(超類)對象。」
在設計繼承時,需符合子類別必須可以替換父類別的功能。
C# 之中有 IEnumerable > ICollection > IList > List
當interface實作時,需這樣宣告
IList<int> myList = new List<int>(); //這就是里氏替換原則
我們在開發程式時,大部分的邏輯都是基於現實生活的,但是在撰寫過程中常常因考慮不周全,導致執行結果正確,但卻不符合現實情況,以下用常用的鳥類分類來解釋:
所有的鳥類都繼承"鳥"這個class
public class bird
{
public void eat(...)
public void fly(...)
public void Location(...)
...
}
所有鳥類都繼承bird這個class這沒有問題,但是有少數鳥類不會飛啊!!
如果讓chicken直接繼承,在程式方面雖然沒錯,但結果不是我們想要的,也不符合實際情況。
public class chicken:bird
{
public void eat(...)
public void fly(...) //chicken不會飛啊
public void Location(...)
...
}
此種問題是因父類別的設計有問題造成的
我們可以藉由增加繼承的層次來解決這個問題
在bird class 下多一層飛行的分類
public class flying:bird //會飛的
{
public void fly(...)
...
}
public class flightless:bird //不會飛的
{
...
}
public class chicken:flyless //繼承不會飛
{
public void eat(...)
public void Location(...)
...
}
如此分開繼承後,上層類別就可透過下層類別來實作,也不改變其行為
這樣既不違背邏輯又可符合開閉原則
里氏替換原則所規範的繼承,子類別必須擁有父類別的全部屬性和方法,避免子類別覆寫父類別的功能(更改傳回結果)
遵守里氏替換原則,可以建立良好的繼承,降低繼承造成的強耦合。